package ar.uade.distribuidas.tpo.dao;

import java.io.File;
import java.io.FileWriter;
import java.io.StringWriter;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.joda.time.DateTime;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import ar.uade.distribuidas.tpo.base.dominiodto.*;
import ar.uade.distribuidas.tpo.web.delegado.BD;

public class FacturaXMLDao {

	static Document doc;
	static final String ARCHIVO = "XML_Factura_Numero";

	/*
	 * public static CotizacionXmlDao getInstance(){ if(instance == null){
	 * instance = new CotizacionXmlDao(); instance.createDocument(); } return
	 * instance; }
	 */
	private FacturaXMLDao() {
	}

	public static String generarFacturaXML(FacturaDTO factura) {
		try {
			// Crea instancia de DocumentBuilderFactory
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			factory.setValidating(false);
			// obtiene objeto DocumentBuilder
			DocumentBuilder docBuilder = factory.newDocumentBuilder();
			// Crea documento DOM en blanco
			doc = docBuilder.newDocument();
			// crea el elemento ra�z y lo agrega al documento
			// Element root = doc.createElement("raiz");
			// doc.appendChild(root);
			// crea comentario y lo agrega a continuaci�n
			Comment comment = doc.createComment("FACTURA");
			doc.appendChild(comment);

			parseFactura(factura);
			saveDomXML(factura.getNumeroFactura());
			
			return toString(doc);

		} catch (Exception e) {
			System.out.println(e.getMessage());
			return "xmlFactura";
		}

	}

	private static void parseFactura(FacturaDTO fact) {
		Element cotElem = doc.createElement("Factura");

		doc.appendChild(cotElem);
		cotElem.setAttribute("numero", String.valueOf(fact.getNumeroFactura()));

		Element auxElemPadre = cotElem.getOwnerDocument().createElement("Fechas");
		Element auxElemHijo = cotElem.getOwnerDocument().createElement("Emision");
		cotElem.appendChild(auxElemPadre);
		auxElemPadre.appendChild(auxElemHijo);
		auxElemHijo.setTextContent(fact.getFechaEmision().toString());
		auxElemHijo = cotElem.getOwnerDocument().createElement("Vencimiento");
		auxElemHijo.setTextContent(fact.getFechaVencimiento().toString());
		auxElemPadre.appendChild(auxElemHijo);

		auxElemPadre = cotElem.getOwnerDocument().createElement("Cliente");
		auxElemHijo = cotElem.getOwnerDocument().createElement("Cuil");
		cotElem.appendChild(auxElemPadre);
		auxElemPadre.appendChild(auxElemHijo);
		auxElemHijo.setTextContent(String.valueOf(fact.getCliente().getCuil()));
		auxElemHijo = cotElem.getOwnerDocument().createElement("RazonSocial");
		auxElemHijo.setTextContent(fact.getCliente().getNombre());
		auxElemPadre.appendChild(auxElemHijo);

		CondicionDeVentaXmlParser.escribirCondicionDeVenta(fact.getCondicionVenta(), cotElem);

		parseItemFactura(fact.getItemsFactura(), cotElem);

	}

	/*
	 * private void createDocument() { DocumentBuilderFactory factory =
	 * DocumentBuilderFactory.newInstance(); DocumentBuilder builder; try {
	 * builder = factory.newDocumentBuilder(); doc = builder.parse(ARCHIVO); }
	 * catch (Exception e) { e.printStackTrace(); } }
	 */

	private static void saveDomXML(int num) {
		// Crea instancia de TransformerFactory
		TransformerFactory tranFactory = TransformerFactory.newInstance();
		Transformer tran;
		try {
			// Crea un objeto Transformer
			tran = tranFactory.newTransformer();
			// interface Source implementada con un documento dom
			Source src = new DOMSource(doc);
			// interface Result implementada con un subtipo de OutputStream
			Result dest = new StreamResult(new FileWriter(new File(ARCHIVO + num + ".xml")));
			// m�todo transform que enlaza el documento con el stream
			tran.transform(src, dest);
			System.out.print("archivo creado con el nombre " + ARCHIVO + num + ".xml");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static void parseItemFactura(List<ItemFacturaDTO> listaItems, Element root) {
		Element auxElemPadre, auxElemHijo, auxNieto;
		
		for (ItemFacturaDTO item : listaItems) {
			RemitoDTO rem = BD.getInstance().getRemitoByNumero(item.getItemRemitoDTO().getNumeroRemito());
 			auxElemPadre = root.getOwnerDocument().createElement("Referencia");
			auxElemHijo = root.getOwnerDocument().createElement("Remito");
			root.appendChild(auxElemPadre);
			auxElemPadre.appendChild(auxElemHijo);

			auxNieto = auxElemHijo.getOwnerDocument().createElement("Numero");
			auxElemHijo.appendChild(auxNieto);
			auxNieto.setTextContent(String.valueOf(item.getItemRemitoDTO().getNumeroRemito()));

			auxNieto = auxElemHijo.getOwnerDocument().createElement("Fecha");
			auxElemHijo.appendChild(auxNieto);
			try{
			auxNieto.setTextContent(rem.getFecha().toString());
			}catch(Exception e){
				auxNieto.setTextContent(DateTime.now().toString());	
			}
			auxElemHijo = root.getOwnerDocument().createElement("Rodamientos");
			auxElemPadre.appendChild(auxElemHijo);
			auxNieto = auxElemHijo.getOwnerDocument().createElement("Item");
			RodamientoDTO cDTO = new RodamientoDTO();
			cDTO.setIdRodamiento(item.getItemRemitoDTO().getItemPedido().getRodamientoId());
			RodamientoDTO rodBase = BD.getInstance().getRodamiento(cDTO);			
			auxNieto.setAttribute("serie", String.valueOf(rodBase.getNroSerie()));
			auxElemHijo.appendChild(auxNieto);

			Element bisnieto = auxNieto.getOwnerDocument().createElement("Sufijo");
			bisnieto.setTextContent(rodBase.getSufijo());
			auxNieto.appendChild(bisnieto);

			bisnieto = auxNieto.getOwnerDocument().createElement("Marca");
			bisnieto.setTextContent(rodBase.getMarca());
			auxNieto.appendChild(bisnieto);

			bisnieto = auxNieto.getOwnerDocument().createElement("Origen");
			bisnieto.setTextContent(rodBase.getPais());
			auxNieto.appendChild(bisnieto);

			/*
			 * bisnieto = auxNieto.getOwnerDocument().createElement("Precio");
			 * TODO: De donde sacar PRECIO???
			 * bisnieto.setTextContent(String.valueOf
			 * (item.getItem().getPrecio())); auxNieto.appendChild(bisnieto);
			 */
			bisnieto = auxNieto.getOwnerDocument().createElement("Cantidad");
			bisnieto.setTextContent(String.valueOf(item.getCantidad()));
			auxNieto.appendChild(bisnieto);
		}
	}

	public static String toString(Document doc) {
		try {
			StringWriter sw = new StringWriter();
			TransformerFactory tf = TransformerFactory.newInstance();
			Transformer transformer = tf.newTransformer();
			transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
			transformer.setOutputProperty(OutputKeys.METHOD, "xml");
			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
			transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");

			transformer.transform(new DOMSource(doc), new StreamResult(sw));
			return sw.toString();
		} catch (Exception ex) {
			throw new RuntimeException("Error converting to String", ex);
		}
	}

}
